﻿using Engine;
using Engine.Graphics;
using Game;

namespace NewST
{
    public abstract class AnimatedBlock : Block
    {
        public abstract int BlockIndex { get; }
        public abstract Texture2D[] Textures { get; }
        public abstract float FrameDuration { get; }

        protected BlockMesh m_standaloneBlockMesh = new BlockMesh();
        private int currentFrame;
        private float frameTimer;
        private int lastFrameTickCount;

        public override void Initialize()
        {
            Model model = ContentManager.Get<Model>("Models/FlatAnimatedBlock");
            Matrix boneAbsoluteTransform = BlockMesh.GetBoneAbsoluteTransform(model.FindMesh("Plate").ParentBone);
            m_standaloneBlockMesh.AppendModelMeshPart(
                model.FindMesh("Plate").MeshParts[0],
                boneAbsoluteTransform * Matrix.CreateTranslation(0f, -0.1f, 0f) * Matrix.CreateRotationX(1.5707f),
                false, false, true, false, Color.White);

            lastFrameTickCount = Environment.TickCount;
            base.Initialize();
        }

        public override void GenerateTerrainVertices(BlockGeometryGenerator generator, TerrainGeometry geometry,
            int value, int x, int y, int z)
        {
            generator.GenerateShadedMeshVertices(this, x, y, z, m_standaloneBlockMesh,
                Color.White, null, null, geometry.SubsetOpaque);
        }

        public override void DrawBlock(PrimitivesRenderer3D primitivesRenderer, int value, Color color,
            float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
        {
            UpdateAnimation();
            DrawCurrentFrame(primitivesRenderer, color, size, ref matrix, environmentData);
        }

        private void UpdateAnimation()
        {
            int currentTick = Environment.TickCount;
            float deltaTime = (currentTick - lastFrameTickCount) / 1000f;
            lastFrameTickCount = currentTick;

            frameTimer += deltaTime;
            if (frameTimer >= FrameDuration)
            {
                frameTimer -= FrameDuration;
                currentFrame = (currentFrame + 1) % Textures.Length;
            }
        }

        private void DrawCurrentFrame(PrimitivesRenderer3D renderer, Color color, float size,
            ref Matrix matrix, DrawBlockEnvironmentData environmentData)
        {
            if (Textures.Length == 0) return;

            BlocksManager.DrawMeshBlock(renderer, m_standaloneBlockMesh,
                Textures[currentFrame], color, 4f * size,
                ref matrix, environmentData);
        }
    }
}
